#!/usr/bin/python2.4
# -*- python -*-
#
# Copyright (C) 2008  Google, Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

'''TsumuFS, a NFS-based caching filesystem.'''

import os
import os.path
import sys
import errno
import stat
import traceback

import pygtk
pygtk.require('2.0')

import gtk
import gobject
import egg.trayicon
import pynotify
import xattr


__version__  = (0, 1)


class TsumufsTrayIcon(object):
  _trayIcon = None
  _tooltips = None
  _eventBox = None
  _displayImage = None

  _mountPointPath = '.'

  _isConnected = False
  _isConflicted = False

  _iconPathPrefix = '../icons'

  def __init__(self):
    pynotify.init('TsumuFS')

    self._trayIcon = egg.trayicon.TrayIcon('TsumuFS')
    self._tooltips = gtk.Tooltips()
    self._eventBox = gtk.EventBox()
    self._eventBox.set_events(gtk.gdk.BUTTON_PRESS_MASK)
    self._displayImage = gtk.Image()
    self._eventBox.add(self._displayImage)
    self._eventBox.connect('button_press_event', self._buttonPress)
    self._trayIcon.connect('delete-event', self._cleanup)
    self._trayIcon.add(self._eventBox)
    self._trayIcon.show_all()

    self._updateIcon()
    gobject.timeout_add(500, self._timer)

  def _updateIcon(self):
    path = ''

    if self._isConnected:
      path = os.path.join(self._iconPathPrefix, 'connected.png')
    else:
      path = os.path.join(self._iconPathPrefix, 'disconnected.png')

    pixbuf = gtk.gdk.pixbuf_new_from_file(path)

    if self._isConflicted:
      path = os.path.join(self._iconPathPrefix, 'conflicted.png')
      pixbuf.blit_from_file(path)

    size = self._trayIcon.get_size()
    pixbuf.scale_simple(size[0], size[1], gtk.gdk.INTERP_BILINEAR)
    self._displayImage.set_from_pixbuf(pixbuf)

  def _cleanup(self, event):
    gtk.main_quit()

  def _timer(self):
    old_isConnected = self._isConnected
    old_isConflicted = self._isConflicted

    try:
      attrs = xattr.xattr(self._mountPointPath)
    except OSError, e:
      gtk.main_quit()

    try:
      if attrs['tsumufs.connected'] == '1':
        self._isConnected = True
      else:
        self._isConnected = False
    except KeyError, e:
      gtk.main_quit()

    if ((old_isConnected != self._isConnected) or
        (old_isConflicted != self._isConflicted)):
      self._updateIcon()

      if not self._isConnected:
        self._notifyDisconnected()

    return True

  def _buttonPress(self, widget, event):
    if event.button == 1:
      pass
    elif event.button == 3:
      pass

  def _notifyDisconnected(self):
    summary = 'Disconnected from NFS'
    body = ('TsumuFS has disconnected from NFS and is now working '
            'completely from the local cache.')

    notification = pynotify.Notification(summary, body)
    notification.attach_to_widget(self._trayIcon)
    notification.show()


def validateMountPoint():
  attrs = xattr.xattr(icon._mountPointPath)
  if not attrs.has_key('tsumufs.version'):
    print >>sys.stderr, ('%s is not a TsumuFS mount point, or is not the root '
                         'of the TsumuFS mount point.' % icon._mountPointPath)
    sys.exit(1)


def daemonize():
  if os.fork() > 0:
    sys.exit(0)

  sys.stderr.close()
  sys.stdout.close()
  sys.stdin.close()


if __name__ == '__main__':
  icon = TsumufsTrayIcon()

  if len(sys.argv) > 1:
    icon._mountPointPath = sys.argv[1]

  validateMountPoint()
  daemonize()
  gtk.main()
